package com.hzx.demo.company;

import android.text.TextUtils;

import com.hzx.demo.LXML.Entity.ControlEntity;
import com.hzx.demo.LXML.LXML;
import com.hzx.demo.util.HZXLog;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

/**
 * 公司移动摄像头的socket辅助类
 * Created by ldkxingzhe on 2016/5/30.
 */
public class SocketHelper {
    private static final String TAG = "SocketHelper";

    private Socket mSocket;
    private BufferedWriter mWriter;
    private BufferedReader mReader;
    private Thread mWriteThread, mReceiverThread, mHeartBeatThread;
    private final List<String> mMessageList = new ArrayList<>();
    private String mSessionId = "0";

    public interface Listener{
        void onMessageCome(String message);
    }
    private Listener mListener;
    public void setListener(Listener listener){
        mListener = listener;
    }

    public void setSessionId(String sessionId){
        if(!TextUtils.isEmpty(sessionId)){
            mSessionId = sessionId;
        }
    }

    public SocketHelper(){
        try {
            mSocket = new Socket("218.247.21.2", 5004);
            startReaderThread();
            startWriterThread();
            startHeartBeatThread();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void startHeartBeatThread() {
        mHeartBeatThread = new Thread(){
            @Override
            public void run() {
                while (true){
                    try {
                        Thread.sleep(60000);
                        if("0".equals(mSessionId)) continue;
                        ControlEntity heartBeatEntity = new ControlEntity();
                        heartBeatEntity.setMsg_id("msg_keep_alive");
                        sendMessage(heartBeatEntity);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        return;
                    }
                }
            }
        };
        mHeartBeatThread.start();
    }

    public void sendMessage(String message){
        synchronized (mMessageList){
            mMessageList.add(message);
            mMessageList.notify();
        }
    }

    public void sendMessage(ControlEntity entity){
        try {
            if(TextUtils.isEmpty(entity.getSession_id()) && !"0".equals(mSessionId)){
                entity.setSession_id(mSessionId);
            }
            String message = LXML.toXML(entity);
            sendMessage(message);
        } catch (Exception e) {
            HZXLog.e(TAG, e.getMessage(), e);
        }
    }

    public void close(){
        System.out.println("socket close");
        try {
            mWriteThread.interrupt();
            mReceiverThread.interrupt();
            mHeartBeatThread.interrupt();
            mWriteThread.join(600);
            mReceiverThread.join(800);
            mSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void startWriterThread() {
        mWriteThread = new Thread(){
            @Override
            public void run() {
                try {
                    mWriter = new BufferedWriter(new OutputStreamWriter(mSocket.getOutputStream()));
                    while (true){
                        List<String> messages;
                        synchronized (mMessageList){
                            if(mMessageList.size() == 0){
                                try {
                                    mMessageList.wait();
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                    return;
                                }
                            }

                            messages = new ArrayList<String>();
                            messages.addAll(mMessageList);
                            mMessageList.clear();
                        }
                        for(String message : messages){
                            mWriter.write(message, 0, message.length());
                            System.out.println("sending message: " + message);
                            byte[] bytes = message.getBytes();
                            printHex(bytes, 0, bytes.length);
                        }
                        mWriter.flush();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        mWriteThread.start();
    }

    private void printHex(byte[] buffer, int offset, int count){
        String h = "";
        for(int i = 0; i < count; i++){
            String temp = Integer.toHexString(buffer[i] & 0xFF);
            if(temp.length() == 1){
                temp = "0" + temp;
            }
            h = h + " "+ temp;
        }
        System.out.println(h);
    }

    private void startReaderThread() {
        mReceiverThread = new Thread(){
            @Override
            public void run() {
                try {
                    mReader = new BufferedReader(new InputStreamReader(mSocket.getInputStream()));
                    System.out.println("start readLine");
                    char[] buffer = new char[1024];
                    int count = 0;
                    while ((count = mReader.read(buffer)) > 0){
                        String result = new String(buffer, 0, count);
                        if(mListener != null){
                            mListener.onMessageCome(result);
                        }else {
                            System.out.println("result is " + result);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        mReceiverThread.start();
    }
}
